/*
 * Copyright 2007-2009 Thomas Krause (thomas@berlin-reloaded.de)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.gidoo.cms.editor.edit;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.IAjaxCallDecorator;
import org.apache.wicket.ajax.calldecorator.AjaxCallDecorator;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.gidoo.cms.GidooCMS;
import org.gidoo.cms.editor.EditorPage;
import org.gidoo.cms.helper.Tools;
import org.gidoo.cms.jcr.EditDataManager;
import org.gidoo.cms.jcr.JcrHelper;
import org.gidoo.cms.login.GidooCMSSession;

/**
 *
 * @author <a href="mailto:thomas@berlin-reloaded.de">Thomas Krause</a>
 */
public class EditPanel extends Panel
{
  
  private Form formEdit;
  
  private String path2Page;

  private Label lblStatus;
  private Label lblCreated;
  private Label lblLastModified;
  private TextField<String> txtTitle;
  private EditorComponent editorComponent;
  private AjaxButton btOk;
  private AjaxButton btPrivate;
  private Button btAbort;
 
  private AjaxSubmitLink lnkPreview;
  private ModalWindow window;
  
  private EditorPage parentPage;
  
  public EditPanel(String id, Node page, EditorPage parent)
  {
    super(id);

    path2Page = "";
    try
    {
      path2Page = JcrHelper.getPartialURLForNode(page);
    }
    catch(RepositoryException ex)
    {
      Logger.getLogger(EditPanel.class.getName()).log(Level.SEVERE, null, ex);
    }

    this.setOutputMarkupId(true);
    
    formEdit =new Form("formEdit");
    add(formEdit);
    
    lblStatus = new Label("lblStatus", new Model(""));
    lblCreated = new Label("lblCreated", new Model(""));
    lblLastModified = new Label("lblLastModified", new Model(""));
    
    add(lblStatus);
    add(lblCreated);
    add(lblLastModified);    
    
    try
    {
      editorComponent = 
        ((GidooCMS) getApplication()).CMS_CONFIGURATION.getEditorComponent().newInstance();
    }
    catch(Exception ex)
    {
      Logger.getLogger(EditPanel.class.getName()).log(Level.SEVERE, getString("editorinstantfailed"), ex);
      error(getString("editorinstantfailed"));
      // fallback
      editorComponent = new SimpleEditorComponent();
    }
    
    txtTitle = new TextField<String>("txtTitle", new Model(""));

    btOk =new AjaxButton("btOk")
    {
      @Override
      protected void onSubmit(AjaxRequestTarget target, Form form)
      {
        updateDB(target, false);
      }

      @Override
      protected IAjaxCallDecorator getAjaxCallDecorator()
      {
        return new AjaxCallDecorator()
        {

          @Override
          public CharSequence decorateScript(CharSequence script)
          {
            return editorComponent.getJavaScriptBeforeSubmit() + "; " + script;
          }

        };
      }
    };
    btOk.setModel(new ResourceModel("ok"));
    btPrivate = new AjaxButton("btPrivate") 
    {

      @Override
      protected void onSubmit(AjaxRequestTarget arg0, Form<?> arg1)
      {
        updateDB(arg0, true);
      }

      @Override
      protected IAjaxCallDecorator getAjaxCallDecorator()
      {
        return new AjaxCallDecorator()
        {

          @Override
          public CharSequence decorateScript(CharSequence script)
          {
            return editorComponent.getJavaScriptBeforeSubmit() + "; " + script;
          }

        };
      }



    };
    btPrivate.setModel(new ResourceModel("private"));
    

    btAbort = new Button("btAbort");
    btAbort.setModel(new ResourceModel("abort"));
    
    lnkPreview = new AjaxSubmitLink("lnkPreview") 
    {
      @Override
      protected void onSubmit(AjaxRequestTarget target, Form form)
      {
        final String content = editorComponent.getText();
        if(((GidooCMS) getApplication()).validate(content, this))
        {

          window.setPageCreator(new PreviewPageCreator(
            parentPage, content, txtTitle.getModelObject(),
            path2Page));
          
          window.setTitle(getString("preview") + ": " + txtTitle.getModelObject());
          window.setUseInitialHeight(true);
          window.setInitialWidth(700);
          window.setInitialHeight(500);
          window.show(target);
        }
        
        target.addComponent(parentPage.getFeedbackPanel());
      }

            @Override
      protected IAjaxCallDecorator getAjaxCallDecorator()
      {
        return new AjaxCallDecorator()
        {

          @Override
          public CharSequence decorateScript(CharSequence script)
          {
            return editorComponent.getJavaScriptBeforeSubmit() + "; " + script;
          }

        };
      }
    };
    
    lnkPreview.setVisible(editorComponent.isPreviewFunctionNeeded());
    
    formEdit.add(editorComponent);
    formEdit.add(txtTitle);
    formEdit.add(btOk);
    formEdit.add(btPrivate);
    formEdit.add(btAbort);
    formEdit.add(lnkPreview);
    
    window = new ModalWindow("window");
    add(window);
    
    updateDataAndView(page, parent);
    
    
  }
  
  public void updateDB(AjaxRequestTarget target, boolean isPrivate)
  {
    Node theNode = parentPage.getCurrentSelectedPage();
    if (theNode == null || target == null)
    {
      return;
    }

    target.addComponent(parentPage.getFeedbackPanel());
    target.addComponent(parentPage.getTreeNav());

    String newContent = editorComponent.getText();

    if(!"".equals(newContent))
    {
      if(!(((GidooCMS) getApplication()).validate(newContent, this)))
        return;
    }
    
    EditDataManager.createDraft(theNode, isPrivate, txtTitle.getModelObject(),
      newContent, (GidooCMSSession) getSession());
    
    lblStatus.setDefaultModelObject(getString("waitingforpublisher"));
    lblStatus.add(new AttributeModifier("style", true, new Model("color:red")));

    parentPage.updateDataAndView();
    
    if(isPrivate)
    {
      info(getString("privatesaved"));
    }
    else
    {
      info(getString("draftsaved"));
    }
  }

  public void updateDataAndView(Node page, EditorPage parent)
  {
    try
    {
      if (parent == null)
      {
        throw new NullPointerException();
      }

      parentPage = parent;

      editorComponent.setEnabled(true);
      editorComponent.enableComponents(true);

      btAbort.setEnabled(true);
      btOk.setEnabled(true);
      txtTitle.setEnabled(true);
      lnkPreview.setEnabled(true);

      Node drafts = ((GidooCMSSession) getSession()).getJcrRootNode().getNode("drafts");
      Node private_drafts = ((GidooCMSSession) getSession()).getJcrRootNode().getNode("private_drafts");
      
      lblCreated.setDefaultModelObject("");
      lblLastModified.setDefaultModelObject("");
      
      if(page == null)
      {
        lblStatus.setDefaultModelObject(getString("null"));

        editorComponent.setEnabled(false);
        editorComponent.enableComponents(false);

        btAbort.setEnabled(false);
        btOk.setEnabled(false);
        txtTitle.setEnabled(false);
        lnkPreview.setEnabled(false);
      }
      else if(private_drafts.hasNode(Tools.path2DraftName(page.getPath().substring(1))))
      {
        Node d = private_drafts.getNode(Tools.path2DraftName(page.getPath().substring(1)));
        lblStatus.setDefaultModelObject(getString("hasprivatedraft"));
        lblStatus.add(new AttributeModifier("style", true, new Model("color:red")));
        
        if(d.hasProperty("cms:created"))
        {
          lblCreated.setDefaultModelObject(
            Tools.standardDateFormatter.format(d.getProperty("cms:created").getDate().getTime()));
        }
        if(d.hasProperty("cms:lastModified"))
        {
          lblLastModified.setDefaultModelObject(
            Tools.standardDateFormatter.format(d.getProperty("cms:lastModified").getDate().getTime()));
        }
        
        editorComponent.setText(d.getProperty("cms:xml").getString());
        txtTitle.setModelObject(d.getProperty("cms:title").getString());
      }
      else if(drafts.hasNode(Tools.path2DraftName(page.getPath().substring(1))))
      {
        Node d = drafts.getNode(Tools.path2DraftName(page.getPath().substring(1)));
        lblStatus.setDefaultModelObject(getString("waitingforpublisher"));
        lblStatus.add(new AttributeModifier("style", true, new Model("color:red")));
        
        if(d.hasProperty("cms:created"))
        {
          lblCreated.setDefaultModelObject(
            Tools.standardDateFormatter.format(d.getProperty("cms:created").getDate().getTime()));
        }
        if(d.hasProperty("cms:lastModified"))
        {
          lblLastModified.setDefaultModelObject(
            Tools.standardDateFormatter.format(d.getProperty("cms:lastModified").getDate().getTime()));
        }
        
        editorComponent.setText(d.getProperty("cms:xml").getString());
        txtTitle.setModelObject(d.getProperty("cms:title").getString());
      }
      else if(JcrHelper.isPublished(page))
      {
        lblStatus.setDefaultModelObject(getString("published"));
        editorComponent.setText(page.getProperty("cms:xml").getString());
        txtTitle.setModelObject(page.getProperty("cms:title").getString());
        
        if(page.hasProperty("cms:created"))
        {
          lblCreated.setDefaultModelObject(
            Tools.standardDateFormatter.format(page.getProperty("cms:created").getDate().getTime()));
        }
        if(page.hasProperty("cms:lastModified"))
        {
          lblLastModified.setDefaultModelObject(
            Tools.standardDateFormatter.format(page.getProperty("cms:lastModified").getDate().getTime()));
        }
        
        
      }
      else
      {
        lblStatus.setDefaultModelObject(getString("isnew"));
        editorComponent.setEnabled(true);
        editorComponent.enableComponents(true);

        if ("".equals(editorComponent.getText()))
        {
          editorComponent.setText(editorComponent.getDefaultXml());
        }
      }
    }
    catch (RepositoryException ex)
    {
      Logger.getLogger(EditPanel.class.getName()).log(Level.SEVERE, null, ex);
      error(getString("jcrerror"));
    }
   
  }  
}
